# 导入相关库和模块
from datetime import datetime
import re
from typing import List, Dict, Union, Any
from config.logging import logger
from models.admin_user import AdminUser, AdminUserSchema
from services.database_manager import databaseManager
from services.auth_handler import AuthHandler


# 定义服务类
class UserApiService:
    def __init__(self, db):
        self.db = db
        self.db_manager = databaseManager(self.db)

    async def user_list(self, page, limit, username=None, email=None) -> Dict[str, Union[List[Any], Any]] :
        """
        角色列表
        :param email:
        :param page:
        :param limit:
        :param username:
        :return:
        """
        query = self.db.query(AdminUser)
        if username:
            query = query.filter(AdminUser.username == username)
        if email:
            query = query.filter(AdminUser.email == email)
        lists = self.db_manager.paginate_query(query, page, limit)
        total_count = query.count()
        # data =  [AdminUserSchema(**role.to_dict()) for role in lists] if lists else {}

        data = [AdminUserSchema.from_orm(role) for role in lists] if lists else []
        # 转换为字典并进行键名转换
        res = [self.db_manager.convert_dict_keys(info.dict()) for info in data]

        return {"list":res,'total':total_count}

    async def register_user(self, userData):
        # 检测是否存在相同的名字或者邮箱
        if self.db_manager.detail_query(AdminUser,
                                        {"email": userData["email"], "username": userData["username"]}) is not None:
            return {"error": "名字或邮箱已存在"}

        userData["hashed_password"] = AuthHandler().get_password_hash(userData["password"])
        userData.pop("password")
        info = self.db_manager.create_entry(AdminUser, userData)

        # 检查 info 是否为字典且包含需要的数据
        if not isinstance(info, dict) or 'hashed_password' not in info:
            return {"error": "用户创建失败，数据库操作未成功"}

        info.pop("hashed_password")
        info["token"] = AuthHandler().create_access_token(info, 24)
        return info

    async def user_role(self):
        """
        绑定管理员用户初始权限
        """

    async def user_login(self, userData):
        """
        登录
        :param userData:
        :return:
        """
        user = {}
        if re.match(r"^\w+@\w+\.\w+$", userData["username"]) is not None:
            user["email"] = userData["username"]
        else:
            user["username"] = userData["username"]
        userData.pop("username")
        # 找出用户信息
        user["status"] = 1
        user["deleted_at"] = None
        info = self.db_manager.detail_query(AdminUser, user)
        if info is None:
            return {"error": "用户不存在"}

        if AuthHandler().verify_password(userData["password"], info["hashed_password"]) is False:
            return {"error": "账号/密码不匹配"}

        return self.db_manager.convert_dict_keys(self.user_data(self.convert_datetime_fields(info)))

    @staticmethod
    def convert_datetime_fields(info: dict):
        """
        把datetime转换
        :param info:
        :return:
        """
        for key, value in info.items():
            if isinstance(value, datetime):
                info[key] = value.isoformat()
        return info

    async def user_detail(self, userId: int):
        """
        用户详情
        :param userId:
        :return:
        """
        res = self.db_manager.detail_query(AdminUser, {"id": userId})
        res = AdminUserSchema.from_orm(res)
        return self.db_manager.convert_dict_keys(res.dict())

    async def user_delete(self, user_id):
        """
        角色列表
        :param user_id:
        :return:
        """
        info = self.db_manager.detail_query(AdminUser, {"id": user_id})
        if info is None:
            return {"error": "用户不存在"}
        res = self.db_manager.detail_update(AdminUser, {"id": user_id},
                                            {"status": 0, "deleted_at": datetime.now().strftime("%Y-%m-%d %H:%M")})
        return res


    @staticmethod
    def user_data(userData):
        """
        生成token和获取用户信息
        :param userData:
        :return:
        """
        userData.pop("hashed_password") if 'hashed_password' in userData.keys() else None
        userData["token"] = AuthHandler().create_access_token(userData, 24)
        return userData
